package ym.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import ym.exception.MyException;
import ym.pojo.User;

import java.util.Date;

/**
 * jwt工具类
 */
public class JWTUtil {
    //签发人
    private static final String ISS_USER = "ym";
    //令牌过期时间(五分钟)
    private static final long TOKEN_EXPIRE_TIME = 5 * 60 * 1000;
    //签名秘钥(最好写的复杂一点)
    private static final String KEY = "dawhfoikawyhdfoiawfgoiawgfioawgfoiagfioawfgoaiwfgaowigfioawgfioaw";

    /**
     * 生成令牌(签名)
     *
     * @return
     */
    public static String token(User user) {
        String token = JWT.create()
                //签发人
                .withIssuer(ISS_USER)
                //签发时间(当前时间)
                .withIssuedAt(new Date())
                //过期时间(当前时间+过期时间)
                .withExpiresAt(new Date(new Date().getTime() + TOKEN_EXPIRE_TIME))
                // 保存用户名
                .withSubject(user.getUsername())
                // 保存用户id
                .withClaim("userId", user.getUserId())
                //加密过的签名秘钥
                .sign(Algorithm.HMAC256(KEY));
        return token;
    }

    /**
     * 校验令牌,返回用户名
     *
     * @param token 传来的令牌
     * @return 用户名
     */
    public static String verifyAndGetUsername(String token) {
        try {
            String username = JWT
                    .require(Algorithm.HMAC256(KEY))
                    .withIssuer(ISS_USER)
                    .build()
                    .verify(token)
                    .getSubject();
            return username;
        } catch (Exception e) {
            throw new MyException(610, "签名解析失败");
        }
    }

    /**
     * 校验令牌,返回用户id
     *
     * @param token 签名字符串
     * @return 用户id
     */
    public static Integer verifyAndGetId(String token) {
        try {
            Integer userId = JWT
                    .require(Algorithm.HMAC256(KEY))
                    .withIssuer(ISS_USER)
                    .build()
                    .verify(token)
                    .getClaim("userId")
                    .asInt();
            return userId;
        } catch (Exception e) {
            throw new MyException(610, "签名解析失败");
        }
    }

}
